package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSkuVo;
import com.spzx.product.api.domain.SkuPriceVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Package: com.spzx.cart.service.impl
 *
 * @Description:
 * @Author xiongkunYang
 * @Create 2025/5/29 11:43
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class CartServiceImpl implements ICartService {

    private final RedisTemplate<Object, Object> redisTemplate;
    private final RemoteProductService remoteProductService;

    private String getCartKey(Long userId) {
        //定义key user:userId:cart
        return "user:cart:" + userId;
    }

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        // 1 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();

        // 2.构建“用户”购物车hash结构key  user:cart:用户ID
        String cartKey = getCartKey(userId);
        // 3.创建Hash结构绑定操作对象（方便对hash进行操作）
        BoundHashOperations<Object, Object, CartInfo> hashOps = this.redisTemplate.boundHashOps(cartKey);
        // 4.判断用户购物车中是否包含该商品 如果包含：数量进行累加(某件商品数量上限99) ：新增购物车商品
        String hashKey = skuId.toString();
        Integer threshold = 99;
        if (Boolean.TRUE.equals(hashOps.hasKey(hashKey))) {
            //4.1 说明该商品在购物车中已有，对数量进行累加 ，不能超过指定上限99
            CartInfo cartInfo = hashOps.get(hashKey);
            cartInfo = cartInfo != null ? cartInfo : new CartInfo();
            int totalCount = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(totalCount > threshold ? threshold : totalCount);
            hashOps.put(hashKey, cartInfo);
        } else {
            //3.判断购物车商品种类（不同SKU）总数大于50件
            Long count = hashOps.size();
            count = count != null ? count : 0;
            if (++count > 50) {
                throw new RuntimeException("商品种类数量超过上限！");
            }
            //4. 说明购物车没有该商品，构建购物车对象，存入Redis
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuNum(skuNum > threshold ? threshold : skuNum);
            //4.1 远程调用商品服务获取商品sku基本信息
            R<ProductSkuVo> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuResult.getCode()) {
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSkuVo productSku = productSkuResult.getData();
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setCreateTime(new Date());

            //4.2 将购物车商品存入Redis
            hashOps.put(hashKey, cartInfo);

        }
    }

    @Override
    public List<CartInfo> getCartList() {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<Object, Object, CartInfo> hashOps = this.redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            return cartInfoList.stream()
                    //降序
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    @Override
    public void deleteCart(Long skuId) {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        //获取缓存对象
        BoundHashOperations<Object, Object, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        hashOps.delete(skuId.toString());
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        // 修改缓存
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<Object, Object, CartInfo> hashOps = this.redisTemplate.boundHashOps(cartKey);
        // 获取用户选择的商品
        if (Boolean.TRUE.equals(hashOps.hasKey(skuId.toString()))) {
            CartInfo cartInfo = hashOps.get(skuId.toString());
            cartInfo = cartInfo != null ? cartInfo : new CartInfo();
            // 写回缓存
            cartInfo.setIsChecked(isChecked);
            // 更新缓存
            hashOps.put(skuId.toString(), cartInfo);
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        // 修改缓存
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<Object, Object, CartInfo> hashOps = this.redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.forEach(cartInfo -> {
                CartInfo cartInfoUpd = hashOps.get(cartInfo.getSkuId().toString());
                cartInfoUpd = cartInfoUpd != null ? cartInfoUpd : new CartInfo();
                cartInfoUpd.setIsChecked(isChecked);
                // 更新缓存
                hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
            });
        }
    }

    @Override
    public void clearCart() {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        //获取缓存对象
        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList() {
        //获取购物车key
        Long userId = SecurityUtils.getUserId();
        String cartKey = getCartKey(userId);

        HashOperations<Object, Object, CartInfo> hashOps = redisTemplate.opsForHash();
        List<CartInfo> carInfoList = hashOps.values(cartKey);
        if (!CollectionUtils.isEmpty(carInfoList)) {
            carInfoList = carInfoList.stream()
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .collect(Collectors.toList());
        }
        return carInfoList;
    }

    @Override
    public Boolean updateCartPrice(Long userId) {
        String cartKey = getCartKey(userId);
        HashOperations<Object, Object, CartInfo> hashOps = redisTemplate.opsForHash();
        List<CartInfo> cartInfoList = hashOps.values(cartKey);

        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.forEach(cartInfo -> {
                R<SkuPriceVo> skuPriceResult = remoteProductService.getSkuPrice(
                        cartInfo.getSkuId(),
                        SecurityConstants.INNER
                );
                if (R.FAIL == skuPriceResult.getCode()) {
                    throw new ServiceException(skuPriceResult.getMsg());
                }
                //实时价格
                cartInfo.setSkuPrice(skuPriceResult.getData().getSalePrice());
                hashOps.put(cartKey, cartInfo.getSkuId().toString(), cartInfo);
            });
        }
        return true;
    }

    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        String cartKey = getCartKey(userId);
        HashOperations<Object, Object, CartInfo> hashOps = redisTemplate.opsForHash();
        List<CartInfo> cartInfoList = hashOps.values(cartKey);

        if (!CollectionUtils.isEmpty(cartInfoList)) {
            //删除选中商品
            cartInfoList.stream()
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .forEach(cartInfo -> hashOps.delete(cartKey, cartInfo.getSkuId().toString()));
        }
        return true;
    }
}